using Microsoft.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.OpenIddict.EntityFrameworkCore;
using UserManagementService.Users;
using UserManagementService.Organizations;

namespace UserManagementService;

/// <summary>
/// UserManagementService 数据库模型配置扩展
/// </summary>
public static class UserManagementServiceDbContextModelCreatingExtensions
{
    /// <summary>
    /// 配置UserManagementService相关实体
    /// </summary>
    public static void ConfigureUserManagementService(this ModelBuilder builder)
    {
        // 配置ABP Identity相关实体
        builder.ConfigureIdentity();
        builder.ConfigureIdentityPro();
        builder.ConfigureOpenIddict();
        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureFeatureManagement();

        // 配置自定义用户实体
        builder.ConfigureUser();
        builder.ConfigureUserRole();
        builder.ConfigureUserLoginHistory();
        builder.ConfigureUserActivityLog();
        builder.ConfigureUserOrganizationUnit();

        // 配置组织实体
        builder.ConfigureOrganization();
        builder.ConfigureOrganizationMember();
    }

    /// <summary>
    /// 配置User实体
    /// </summary>
    private static void ConfigureUser(this ModelBuilder builder)
    {
        builder.Entity<User>(b =>
        {
            b.ToTable("AppUsers", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 基础属性
            b.Property(x => x.UserName)
                .IsRequired()
                .HasMaxLength(256);

            b.Property(x => x.Email)
                .IsRequired()
                .HasMaxLength(256);

            b.Property(x => x.PhoneNumber)
                .HasMaxLength(16);

            b.Property(x => x.Name)
                .HasMaxLength(64);

            b.Property(x => x.Surname)
                .HasMaxLength(64);

            b.Property(x => x.DisplayName)
                .HasMaxLength(129); // Name(64) + Space(1) + Surname(64)

            b.Property(x => x.AvatarUrl)
                .HasMaxLength(512);

            b.Property(x => x.Bio)
                .HasMaxLength(1000);

            b.Property(x => x.PasswordHash)
                .IsRequired()
                .HasMaxLength(512);

            b.Property(x => x.SecurityStamp)
                .IsRequired()
                .HasMaxLength(512);

            b.Property(x => x.TwoFactorEnabled)
                .HasMaxLength(64);

            b.Property(x => x.LastLoginIp)
                .HasMaxLength(45); // IPv6最大长度

            // 索引
            b.HasIndex(x => x.UserName).IsUnique();
            b.HasIndex(x => x.Email).IsUnique();
            b.HasIndex(x => x.PhoneNumber);
            b.HasIndex(x => x.Status);
            b.HasIndex(x => x.UserType);
            b.HasIndex(x => x.IsActive);
            b.HasIndex(x => x.TenantId);
            b.HasIndex(x => x.LastLoginTime);

            // 多租户配置
            b.ConfigureMultiTenant();

            // 软删除配置
            b.ConfigureSoftDelete();
        });
    }

    /// <summary>
    /// 配置UserRole实体
    /// </summary>
    private static void ConfigureUserRole(this ModelBuilder builder)
    {
        builder.Entity<UserRole>(b =>
        {
            b.ToTable("AppUserRoles", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.RoleName)
                .HasMaxLength(256);

            b.Property(x => x.Remark)
                .HasMaxLength(500);

            // 索引
            b.HasIndex(x => new { x.UserId, x.RoleId }).IsUnique();
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.RoleId);
            b.HasIndex(x => x.IsEnabled);
            b.HasIndex(x => x.ExpiresAt);
            b.HasIndex(x => x.TenantId);

            // 多租户配置
            b.ConfigureMultiTenant();
        });
    }

    /// <summary>
    /// 配置UserLoginHistory实体
    /// </summary>
    private static void ConfigureUserLoginHistory(this ModelBuilder builder)
    {
        builder.Entity<UserLoginHistory>(b =>
        {
            b.ToTable("AppUserLoginHistories", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.IpAddress)
                .HasMaxLength(64);

            b.Property(x => x.BrowserInfo)
                .HasMaxLength(512);

            b.Property(x => x.OperatingSystem)
                .HasMaxLength(256);

            b.Property(x => x.DeviceInfo)
                .HasMaxLength(256);

            b.Property(x => x.Location)
                .HasMaxLength(256);

            b.Property(x => x.FailureReason)
                .HasMaxLength(256);

            b.Property(x => x.SessionId)
                .HasMaxLength(128);

            // 索引
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.LoginTime);
            b.HasIndex(x => x.Status);
            b.HasIndex(x => x.LoginType);
            b.HasIndex(x => x.IpAddress);
            b.HasIndex(x => x.TenantId);

            // 多租户配置
            b.ConfigureMultiTenant();
        });
    }

    /// <summary>
    /// 配置UserActivityLog实体
    /// </summary>
    private static void ConfigureUserActivityLog(this ModelBuilder builder)
    {
        builder.Entity<UserActivityLog>(b =>
        {
            b.ToTable("AppUserActivityLogs", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.Description)
                .IsRequired()
                .HasMaxLength(1000);

            b.Property(x => x.RequestUrl)
                .HasMaxLength(2048);

            b.Property(x => x.RequestMethod)
                .HasMaxLength(16);

            b.Property(x => x.IpAddress)
                .HasMaxLength(64);

            b.Property(x => x.UserAgent)
                .HasMaxLength(1024);

            b.Property(x => x.BrowserInfo)
                .HasMaxLength(512);

            b.Property(x => x.OperatingSystem)
                .HasMaxLength(256);

            b.Property(x => x.DeviceInfo)
                .HasMaxLength(256);

            b.Property(x => x.Location)
                .HasMaxLength(256);

            b.Property(x => x.ErrorMessage)
                .HasMaxLength(1000);

            b.Property(x => x.Metadata)
                .HasMaxLength(4000);

            b.Property(x => x.SessionId)
                .HasMaxLength(128);

            b.Property(x => x.RelatedEntityType)
                .HasMaxLength(128);

            // 索引
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.ActivityType);
            b.HasIndex(x => x.CreationTime);
            b.HasIndex(x => x.Result);
            b.HasIndex(x => x.TenantId);
            b.HasIndex(x => new { x.UserId, x.CreationTime });

            // 多租户配置
            b.ConfigureMultiTenant();
        });
    }

    /// <summary>
    /// 配置UserOrganizationUnit实体
    /// </summary>
    private static void ConfigureUserOrganizationUnit(this ModelBuilder builder)
    {
        builder.Entity<UserOrganizationUnit>(b =>
        {
            b.ToTable("AppUserOrganizationUnits", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.OrganizationName)
                .HasMaxLength(256);

            b.Property(x => x.Position)
                .HasMaxLength(128);

            b.Property(x => x.Remark)
                .HasMaxLength(500);

            // 索引
            b.HasIndex(x => new { x.UserId, x.OrganizationId }).IsUnique();
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.OrganizationId);
            b.HasIndex(x => x.IsEnabled);
            b.HasIndex(x => x.Level);
            b.HasIndex(x => x.IsManager);
            b.HasIndex(x => x.TenantId);

            // 多租户配置
            b.ConfigureMultiTenant();
        });
    }

    /// <summary>
    /// 配置Organization实体
    /// </summary>
    private static void ConfigureOrganization(this ModelBuilder builder)
    {
        builder.Entity<Organizations.Organization>(b =>
        {
            b.ToTable("AppOrganizations", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.Name)
                .IsRequired()
                .HasMaxLength(256);

            b.Property(x => x.Code)
                .IsRequired()
                .HasMaxLength(64);

            b.Property(x => x.Description)
                .HasMaxLength(1000);

            // 索引
            b.HasIndex(x => x.Code).IsUnique();
            b.HasIndex(x => x.ParentId);
            b.HasIndex(x => x.Status);
            b.HasIndex(x => x.Type);
            b.HasIndex(x => x.TenantId);

            // 多租户配置
            b.ConfigureMultiTenant();

            // 软删除配置
            b.ConfigureSoftDelete();
        });
    }

    /// <summary>
    /// 配置OrganizationMember实体
    /// </summary>
    private static void ConfigureOrganizationMember(this ModelBuilder builder)
    {
        builder.Entity<OrganizationMember>(b =>
        {
            b.ToTable("AppOrganizationMembers", "UserManagement");

            // 主键
            b.HasKey(x => x.Id);

            // 属性
            b.Property(x => x.Position)
                .HasMaxLength(128);

            b.Property(x => x.Remark)
                .HasMaxLength(500);

            // 索引
            b.HasIndex(x => new { x.OrganizationId, x.UserId }).IsUnique();
            b.HasIndex(x => x.OrganizationId);
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.Status);
            b.HasIndex(x => x.Level);
            b.HasIndex(x => x.IsManager);
            b.HasIndex(x => x.TenantId);

            // 多租户配置
            b.ConfigureMultiTenant();

            // 软删除配置
            b.ConfigureSoftDelete();
        });
    }
}